package com.gxwy.shenzhou;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.CharBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TCPServer implements Runnable {
	private ServerSocket serverSocket;
	private Socket socket;
	private String ipaddr;
	private int port = 10000;
	ShenZhouMessageHandler m_handler;
	private ExecutorService executeService = Executors.newFixedThreadPool(10);
	private boolean runningFlag = true;
	public TCPServer(String ipAddr, int ipPort,ShenZhouMessageHandler handler) throws UnknownHostException, IOException{
		ipaddr = ipAddr;
		port = ipPort;
		m_handler = handler;
		serverSocket = new ServerSocket(port, 10, InetAddress.getByName(ipaddr));
//		serverSocket = new ServerSocket(port);			
		System.out.println("SocketServer have been started.[" + serverSocket + "]");
	}

	public void run() {
		startServer();
	}
	
	public void stopServer()
	{
		runningFlag = false;
		try {
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		runningFlag = false;
	}
	public void startServer()
	{
		try {
			while(runningFlag){
					socket = serverSocket.accept();
					executeService.submit(new Runnable(){
						public void run(){
							int messageLen = 0;
							try{
								BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
								PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
								
								CharBuffer charbuf = CharBuffer.allocate(2048);
								int messagetmp =  in.read(charbuf);
								if (messageLen == -1) 
								{
									System.out.println("client socket is closed.");
									return;
								}
						
								messageLen = messageLen + messagetmp;
								String messageStr = MessageFactory.getIntegrateMessage(charbuf,messageLen);
								
								while (messageStr == null) {
									System.out.println(charbuf.toString());
									CharBuffer tmpbuf = CharBuffer.allocate(1024);
									messagetmp = in.read(tmpbuf);
									if (messagetmp == -1)
									{
										System.out.println("client socket is closed, some bytes have been lost.");
										return;										
									}
									charbuf.append(tmpbuf);									
									messageLen = messageLen + messagetmp;
									messageStr = MessageFactory.getIntegrateMessage(charbuf,messageLen);
								}
								System.out.println("Server Received:[" + messageStr + "]");
								String response = m_handler.processMessage(messageStr);
								out.print(response);
								out.close();
								in.close();
							}catch (Exception e) {
								e.printStackTrace();
							}finally{
								/*
								try {
									socket.close();
								} catch (IOException e) {
									System.out.println("close socket error.");
									e.printStackTrace();
								}
								*/
							}
						}
					});
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(null != serverSocket){
					serverSocket.close();
					System.out.println("serverSocket close");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}


	public static void main(String[] args) throws InterruptedException {
//		ShenZhouMessageHandler crr = new ShenZhouMessageHandler() {
//
//			public String processMessage(String message) {
//				System.out
//						.println("receive message from client:[" + message + "]");
//				return "serverResponse";
//			}
//
//		};
//		KaiHuReceiveMessage crr=new KaiHuReceiveMessage();
//		SelectShouXuFeiReciveMessage crr=new SelectShouXuFeiReciveMessage();
		ZhangHuXinXiChaXunReciveMessage crr=new ZhangHuXinXiChaXunReciveMessage();
		TCPServer tcpServer = null;
		try {
			tcpServer = new TCPServer("192.168.3.129",10001,crr); //192.168.0.1
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		
		Thread serverTthread = new Thread(tcpServer);
		serverTthread.start();
		while (true)
			Thread.sleep(1000);
		/*
		Thread clientThread = new Thread(new Runnable(){
				public void run(){
					new SocketClient();
				}
		});
		clientThread.start();
		*/
	}
}